package com.xyht.sca_s.student_manage_system.modules.signUp.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xyht.sca_s.student_manage_system.common.commonReturn.CommonCodeEnum;
import com.xyht.sca_s.student_manage_system.common.commonReturn.CommonResult;
import com.xyht.sca_s.student_manage_system.common.commonReturn.ResponseResult;
import com.xyht.sca_s.student_manage_system.common.util.ApiModelUtil;
import com.xyht.sca_s.student_manage_system.common.util.TimeUtil;
import com.xyht.sca_s.student_manage_system.modules.org.entity.OrgNode;
import com.xyht.sca_s.student_manage_system.modules.org.util.NodeUtil;
import com.xyht.sca_s.student_manage_system.modules.signUp.entity.SmsOrgStructureCopy;
import com.xyht.sca_s.student_manage_system.modules.signUp.entity.SmsOrgUserRelationCopy;
import com.xyht.sca_s.student_manage_system.modules.signUp.entity.SmsSignUpSystem;
import com.xyht.sca_s.student_manage_system.modules.signUp.entity.SmsUserStudentRelationCopy;
import com.xyht.sca_s.student_manage_system.modules.signUp.entity.dto.SmsOrgStructureDTO;
import com.xyht.sca_s.student_manage_system.modules.signUp.entity.dto.SmsSignUpSystemDTO;
import com.xyht.sca_s.student_manage_system.modules.signUp.entity.vo.SmsSignUpExportVO;
import com.xyht.sca_s.student_manage_system.modules.signUp.entity.vo.SmsSignUpSystemVO;
import com.xyht.sca_s.student_manage_system.modules.signUp.mapper.SmsOrgStructureCopyMapper;
import com.xyht.sca_s.student_manage_system.modules.signUp.mapper.SmsOrgUserRelationCopyMapper;
import com.xyht.sca_s.student_manage_system.modules.signUp.mapper.SmsSignUpSystemMapper;
import com.xyht.sca_s.student_manage_system.modules.signUp.mapper.SmsUserStudentRelationCopyMapper;
import com.xyht.sca_s.student_manage_system.modules.signUp.service.SmsSignUpSystemService;
import com.xyht.sca_s.student_manage_system.modules.user.entity.SmsUser;
import com.xyht.sca_s.student_manage_system.modules.user.mapper.SmsUserMapper;
import org.apache.poi.hssf.usermodel.*;
import org.apache.poi.ss.usermodel.FillPatternType;
import org.apache.poi.ss.usermodel.IndexedColors;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletResponse;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.concurrent.Future;
import java.util.stream.Collectors;

import static com.xyht.sca_s.student_manage_system.common.util.ParamCheckUtil.isNullOrEmpty;
import static com.xyht.sca_s.student_manage_system.modules.signUp.constant.SignUpOrgType.ORG_TYPE_MAJOR;
import static com.xyht.sca_s.student_manage_system.modules.signUp.constant.SmsSignUpCommonConstant.PER_SHEET_NUM;
import static com.xyht.sca_s.student_manage_system.modules.user.constant.TeacherAndStudentFlag.STUDENT_FLAG;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author XYHT
 * @since 2023-05-08
 */
@Service
public class SmsSignUpSystemServiceImpl extends ServiceImpl<SmsSignUpSystemMapper, SmsSignUpSystem> implements SmsSignUpSystemService {
    @Autowired
    SmsSignUpSystemMapper smsSignUpSystemMapper;
    @Autowired
    SmsOrgStructureCopyMapper smsOrgStructureCopyMapper;
    @Autowired
    SmsUserStudentRelationCopyMapper smsUserStudentRelationCopyMapper;
    @Autowired
    SmsOrgUserRelationCopyMapper smsOrgUserRelationCopyMapper;
    @Autowired
    SmsUserMapper smsUserMapper;
//    @Autowired
//    SmsUserStudentRelationMapper smsUserStudentRelationMapper;
    @Autowired
    private ApiModelUtil apiModelUtil;
    @Override
    public ResponseResult smsSignUpSystemAdd(SmsSignUpSystemVO smsSignUpSystemVO) {
        if(
            isNullOrEmpty(smsSignUpSystemVO.getStudentMajor())||
            isNullOrEmpty(smsSignUpSystemVO.getStudentCollege())||
            isNullOrEmpty(smsSignUpSystemVO.getStudentCity())||
            isNullOrEmpty(smsSignUpSystemVO.getStudentArea())||
            isNullOrEmpty(smsSignUpSystemVO.getStudentName())||
            isNullOrEmpty(smsSignUpSystemVO.getStudentPhone())||
            isNullOrEmpty(smsSignUpSystemVO.getStudentSchool())||
            isNullOrEmpty(smsSignUpSystemVO.getStudentSex())||
            isNullOrEmpty(smsSignUpSystemVO.getStudentProvince())){
            return CommonResult.failed(CommonCodeEnum.INVALID_PARAM);
        }
        SmsSignUpSystem smsSignUpSystem = new SmsSignUpSystem();

        smsSignUpSystem.setStudentArea(smsSignUpSystemVO.getStudentArea());
        smsSignUpSystem.setStudentCity(smsSignUpSystemVO.getStudentCity());
        smsSignUpSystem.setStudentBookTime(smsSignUpSystemVO.getStudentBookTime());
        smsSignUpSystem.setStudentName(smsSignUpSystemVO.getStudentName());
        smsSignUpSystem.setStudentQq(smsSignUpSystemVO.getStudentQq());
        smsSignUpSystem.setStudentPhone(smsSignUpSystemVO.getStudentPhone());
        smsSignUpSystem.setStudentSchool(smsSignUpSystemVO.getStudentSchool());
        smsSignUpSystem.setStudentCollege(smsSignUpSystemVO.getStudentCollege());
        smsSignUpSystem.setStudentMajor(smsSignUpSystemVO.getStudentMajor());
        smsSignUpSystem.setStudentSex(smsSignUpSystemVO.getStudentSex());
        smsSignUpSystem.setStudentWx(smsSignUpSystemVO.getStudentWx());
        smsSignUpSystem.setStudentProvince(smsSignUpSystemVO.getStudentProvince());
        QueryWrapper<SmsSignUpSystem> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(SmsSignUpSystem::getStudentPhone,smsSignUpSystemVO.getStudentPhone());
        SmsSignUpSystem query = smsSignUpSystemMapper.selectOne(queryWrapper);
        if(!isNullOrEmpty(query)){
            return CommonResult.failed(CommonCodeEnum.STUDENT_SIGN_UP_PHONE_REPEAT);
        }
        smsSignUpSystemMapper.insert(smsSignUpSystem);
        return CommonResult.success();
    }

    //后端查询学生报名申请
    @Override
    public ResponseResult selectSmsSignUpSystem(String student_name,
                                                String province_name,
                                                String major_name,
                                                Integer pageSize,
                                                Integer pageNum,
                                                String bg_date,
                                                String end_date) {
        Date bgDate = null;
        Date endDate = null;
        List<SmsSignUpSystem> list11 = new ArrayList<>();
        if (!isNullOrEmpty(bg_date)) {
            bgDate = TimeUtil.StringtoDate(bg_date);
        }
        if (!isNullOrEmpty(end_date)) {
            endDate = TimeUtil.StringtoDate(end_date);

        }
        QueryWrapper<SmsSignUpSystem> queryWrapper = new QueryWrapper<>();
        if (isNullOrEmpty(queryWrapper)) {
            return CommonResult.failed(CommonCodeEnum.DATA_NOT_FOUND);
        }
        if (bgDate != null) {
            queryWrapper.lambda().ge(SmsSignUpSystem::getCreateTime, bgDate);
        }
        if (endDate != null) {
            queryWrapper.lambda().le(SmsSignUpSystem::getCreateTime, endDate);
        }
        if (!isNullOrEmpty(student_name)) {
            queryWrapper.lambda().like(SmsSignUpSystem::getStudentName, student_name);
        }
        if (!isNullOrEmpty(province_name)) {
            queryWrapper.lambda().like(SmsSignUpSystem::getStudentProvince, province_name);
        }
        if (!isNullOrEmpty(major_name)) {
            queryWrapper.lambda().like(SmsSignUpSystem::getStudentMajor, major_name);
        }
        List<SmsSignUpSystem> list1 = smsSignUpSystemMapper.selectList(queryWrapper);
        if (list1.size() == 0) {
            return CommonResult.success(list11,0);
        }
        queryWrapper.orderByDesc("create_time");
        Page<SmsSignUpSystem> page = new Page<>(pageNum, pageSize);
        smsSignUpSystemMapper.selectPage(page, queryWrapper);
        list11 = page.getRecords();
        List<SmsSignUpSystemDTO> list =new ArrayList<>();
        if(!isNullOrEmpty(list11)&&list11.size()>0){
            for(SmsSignUpSystem signUpSystem : list11){
                SmsSignUpSystemDTO smsSignUpSystemDTO = new SmsSignUpSystemDTO();
                BeanUtils.copyProperties(signUpSystem,smsSignUpSystemDTO);
                list.add(smsSignUpSystemDTO);
            }
        }
        int total = (int) page.getTotal();
        return CommonResult.success(list, total);
    }

    @Override
    public ResponseResult selectSmsSignUpSystemById(String id) {
        SmsSignUpSystem query = smsSignUpSystemMapper.selectById(id);
        if(isNullOrEmpty(query)){
            return CommonResult.failed(CommonCodeEnum.DATA_NOT_FOUND);
        }
        SmsSignUpSystem smsSignUpSystem = new SmsSignUpSystem();
        smsSignUpSystem.setId(id);
        SmsSignUpSystemDTO smsSignUpSystemDTO = new SmsSignUpSystemDTO();
        BeanUtils.copyProperties(query,smsSignUpSystemDTO);
        return CommonResult.success(smsSignUpSystemDTO);
    }

    @Override
    public ResponseResult selectSmsSignUpOrgSystem(Integer type,String parent_id) {
        List<SmsOrgStructureDTO> list1 = new ArrayList<>();
        if(type==ORG_TYPE_MAJOR){//专业
            if(isNullOrEmpty(parent_id)){
                return CommonResult.failed(CommonCodeEnum.INVALID_PARAM);
            }
        }
        QueryWrapper<SmsOrgStructureCopy> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(SmsOrgStructureCopy::getLevel,type);
        if(type==ORG_TYPE_MAJOR){
            queryWrapper.lambda().eq(SmsOrgStructureCopy::getParentId,parent_id);
        }

        List<SmsOrgStructureCopy> list = smsOrgStructureCopyMapper.selectList(queryWrapper);
        if(isNullOrEmpty(list)||list.size()==0){
            return CommonResult.success(list1,0);
        }
        for(SmsOrgStructureCopy structure:list){
            SmsOrgStructureDTO smsOrgStructureDTO = new SmsOrgStructureDTO();
            BeanUtils.copyProperties(structure,smsOrgStructureDTO);
//            QueryWrapper<SmsOrgStructure> query = new QueryWrapper<>();
//            query.lambda().ne(SmsOrgStructure::getOrgName,"南充电影工业职业学院");
//            List<SmsOrgStructure> list2 = smsOrgStructureMapper.selectList(query);
            if(!structure.getOrgName().equals("南充电影工业职业学院")){
                list1.add(smsOrgStructureDTO);
            }
        }

        return CommonResult.success(list1);
    }

    @Override
    public ResponseResult deleteSmsSignUpSystem(SmsSignUpSystemVO smsSignUpSystemVO) {
        if(isNullOrEmpty(smsSignUpSystemVO.getId())){
            return CommonResult.failed(CommonCodeEnum.INVALID_PARAM);
        }
        SmsSignUpSystem query = smsSignUpSystemMapper.selectById(smsSignUpSystemVO.getId());
        if(query==null){
            return CommonResult.failed(CommonCodeEnum.DATA_NOT_FOUND);
        }
        smsSignUpSystemMapper.deleteById(smsSignUpSystemVO.getId());
        return CommonResult.success();
    }

    @Override
    public Future<String> exportSmsSignUpSystem(SmsSignUpExportVO smsSignUpExportVO, HttpServletResponse response) {
        try {
            List<SmsSignUpSystemDTO> respList = new ArrayList<>();
            int total = 0;
            List<String> stuIDList = null;
            Integer org_id = smsSignUpExportVO.getId();
            if (org_id != null) {
                QueryWrapper<SmsOrgStructureCopy> queryWrapper = new QueryWrapper<>();
                List<SmsOrgStructureCopy> list = smsOrgStructureCopyMapper.selectList(queryWrapper);
                List<OrgNode> orgNodes = new ArrayList<>();
                for (SmsOrgStructureCopy smsOrgStructure : list) {
                    OrgNode orgNode = new OrgNode();
                    BeanUtils.copyProperties(smsOrgStructure, orgNode);
                    orgNodes.add(orgNode);
                }
                List<Integer> orgList = NodeUtil.getChildNodes(orgNodes, org_id);
                if (orgList == null || orgList.size() < 1) {
                    return null;
                }

                List<SmsOrgUserRelationCopy> orgUserRelationList = smsOrgUserRelationCopyMapper
                        .selectList(new QueryWrapper<SmsOrgUserRelationCopy>().lambda().in(SmsOrgUserRelationCopy::getOrgId, orgList));
                List<String> userList = orgUserRelationList.stream().map(SmsOrgUserRelationCopy::getUserId).collect(Collectors.toList());
                if (userList.size() < 1) {
                    return null;
                }

                List<SmsUser> userInfoList = smsUserMapper
                        .selectList(new QueryWrapper<SmsUser>().lambda().in(SmsUser::getId, userList).eq(SmsUser::getFlag, STUDENT_FLAG));
                List<String> userIDList = userInfoList.stream().map(SmsUser::getId).collect(Collectors.toList());
                if (userIDList.size() < 1) {
                    return null;
                }

                List<SmsUserStudentRelationCopy> userStudentRelationList = smsUserStudentRelationCopyMapper
                        .selectList(new QueryWrapper<SmsUserStudentRelationCopy>().lambda().in(SmsUserStudentRelationCopy::getUserId, userIDList));
                stuIDList = userStudentRelationList.stream().map(SmsUserStudentRelationCopy::getStuId).collect(Collectors.toList());
                if (stuIDList.size() < 1) {
                    return null;
                }
            }

            QueryWrapper<SmsSignUpSystem> queryWrapper = new QueryWrapper<>();
            queryWrapper.lambda().orderByDesc(SmsSignUpSystem::getCreateTime);
            if (stuIDList != null && stuIDList.size() > 1) {
                queryWrapper.lambda().in(SmsSignUpSystem::getId, stuIDList);
            }
            if (!isNullOrEmpty(smsSignUpExportVO.getStudentCollege())) {
                queryWrapper.lambda().like(SmsSignUpSystem::getStudentCollege, smsSignUpExportVO.getStudentCollege());
            }
            if (!isNullOrEmpty(smsSignUpExportVO.getStudentMajor())) {
                queryWrapper.lambda().like(SmsSignUpSystem::getStudentMajor, smsSignUpExportVO.getStudentMajor());
            }
            if(!isNullOrEmpty(smsSignUpExportVO.getStudentArea())){
                queryWrapper.lambda().like(SmsSignUpSystem::getStudentArea,smsSignUpExportVO.getStudentArea());
            }
            if(!isNullOrEmpty(smsSignUpExportVO.getStudentName())){
                queryWrapper.lambda().like(SmsSignUpSystem::getStudentName,smsSignUpExportVO.getStudentName());
            }
            if(!isNullOrEmpty(smsSignUpExportVO.getStudentCity())){
                queryWrapper.lambda().like(SmsSignUpSystem::getStudentCity,smsSignUpExportVO.getStudentCity());
            }
            if(!isNullOrEmpty(smsSignUpExportVO.getStudentPhone())){
                queryWrapper.lambda().like(SmsSignUpSystem::getStudentPhone,smsSignUpExportVO.getStudentPhone());
            }
            if(!isNullOrEmpty(smsSignUpExportVO.getStudentProvince())){
                queryWrapper.lambda().like(SmsSignUpSystem::getStudentProvince,smsSignUpExportVO.getStudentProvince());
            }
            if(!isNullOrEmpty(smsSignUpExportVO.getStudentSex())){
                queryWrapper.lambda().like(SmsSignUpSystem::getStudentSex,smsSignUpExportVO.getStudentSex());
            }
            if(!isNullOrEmpty(smsSignUpExportVO.getStudentBookTime())){
                queryWrapper.lambda().like(SmsSignUpSystem::getStudentBookTime,smsSignUpExportVO.getStudentBookTime());
            }
            if(!isNullOrEmpty(smsSignUpExportVO.getStudentQq())){
                queryWrapper.lambda().like(SmsSignUpSystem::getStudentQq,smsSignUpExportVO.getStudentQq());
            }
            if(!isNullOrEmpty(smsSignUpExportVO.getStudentSchool())){
                queryWrapper.lambda().like(SmsSignUpSystem::getStudentSchool,smsSignUpExportVO.getStudentSchool());
            }
            if (!isNullOrEmpty(smsSignUpExportVO.getSearchStr())) {
                String searchStr = smsSignUpExportVO.getSearchStr();
                queryWrapper.lambda().and(smsSmsSignUpLambdaQueryWrapper -> smsSmsSignUpLambdaQueryWrapper.like(SmsSignUpSystem::getStudentName, searchStr)
                        .or()
                        .like(SmsSignUpSystem::getStudentCollege, searchStr)
                        .or()
                        .like(SmsSignUpSystem::getStudentMajor, searchStr)
                        .or()
                        .like(SmsSignUpSystem::getStudentBookTime, searchStr)
                        .or()
                        .like(SmsSignUpSystem::getStudentProvince, searchStr)
                        .or()
                        .like(SmsSignUpSystem::getStudentCity, searchStr)
                        .or()
                        .like(SmsSignUpSystem::getStudentPhone, searchStr));
            }
            List<SmsSignUpSystem> list = smsSignUpSystemMapper.selectList(queryWrapper);
            //表头数据
            String[] header = smsSignUpExportVO.getLimitColumn().toArray(new String[0]);
            double sheetNum;
            //声明一个工作簿
            HSSFWorkbook workbook = new HSSFWorkbook();
            if (list != null && list.size() > 0) {
                sheetNum = Math.ceil((double) list.size() / PER_SHEET_NUM);
                for (int k = 0; k < sheetNum; k++) {
                    //生成一个表格，设置表格名称为"资源导出表"
                    HSSFSheet sheet = workbook.createSheet("资源导出表" + (k + 1));

                    //设置表格列宽度为10个字节
                    sheet.setDefaultColumnWidth(12);
                    //创建标题的显示样式
                    HSSFCellStyle headerStyle = workbook.createCellStyle();
                    headerStyle.setFillForegroundColor(IndexedColors.YELLOW.index);
                    headerStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);

                    HSSFFont f = workbook.createFont();
                    f.setFontHeightInPoints((short) 10);//字号
                    f.setBold(true);//加粗
                    headerStyle.setFont(f);
                    //创建第一行表头
                    HSSFRow headrow = sheet.createRow(0);

                    //遍历添加表头(下面模拟遍历学生，也是同样的操作过程)
                    for (int i = 0; i < header.length + 1; i++) {
                        //创建一个单元格
                        HSSFCell cell = headrow.createCell(i);

                        if (i == 0) {
                            //创建一个内容对象
                            HSSFRichTextString text = new HSSFRichTextString("序号");
                            //将内容对象的文字内容写入到单元格中
                            cell.setCellValue(text);
                            cell.setCellStyle(headerStyle);
                            continue;
                        }
                        //创建一个内容对象
                        String header1 = apiModelUtil.getFieldValueByFieldName(SmsSignUpSystem.class, header[i - 1]);
                        HSSFRichTextString text = new HSSFRichTextString(header1);

                        //将内容对象的文字内容写入到单元格中
                        cell.setCellValue(text);
                        cell.setCellStyle(headerStyle);
                    }

                    int range = PER_SHEET_NUM;
                    if (k + 1 == sheetNum) {
                        range = list.size() - (PER_SHEET_NUM) * k;
                    }
                    for (int i = 0; i < range; i++) {
                        //创建一行
                        HSSFRow row1 = sheet.createRow(i + 1);
                        SmsSignUpSystem getsummary = list.get((PER_SHEET_NUM) * k + i);
                        Map map = JSONObject.parseObject(JSON.toJSONString(getsummary), Map.class);
                        row1.createCell(0).setCellValue(new HSSFRichTextString(i + 1 + ""));
                        for (int j = 0; j < header.length; j++) {
                            String rowContent = "";
                            if (map.get(header[j]) instanceof Long){
                                rowContent = TimeUtil.DateformatTimestamp((long)map.get(header[j]));
                            }else if(header[j].equals("studentSex")){
                                if (String.valueOf(map.get(header[j])).equals("0")){
                                    rowContent = "男";
                                }else{
                                    rowContent = "女";
                                }
                            }
                            else{
                                rowContent = String.valueOf(map.get(header[j])) ;
                            }
                            row1.createCell(j + 1).setCellValue(new HSSFRichTextString(rowContent));
                        }

                    }
                }
            }
//            response.setContentType(MediaType.APPLICATION_OCTET_STREAM_VALUE);
            response.setContentType("application/vnd.ms-excel");
            response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode("学生预报名信息导出表.xlsx", "utf-8"));
            response.setHeader("file-type","download");
            response.setHeader("file-name", URLEncoder.encode("学生预报名信息导出表.xlsx", "utf-8"));
            response.setHeader("Access-Control-Expose-Headers", "file-type,file-name");
            //刷新缓冲
            response.flushBuffer();
            //workbook将Excel写入到response的输出流中，供页面下载
            workbook.write(response.getOutputStream());
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }
}
